<!DOCTYPE html><!--  Last Published: Mon Feb 19 2024 01:36:14 GMT+0000 (Coordinated Universal Time)  -->
<html data-wf-page="6597869d893a2d5b14e63c49" data-wf-site="657c661418a503e0b43c9905">
<head>
  <meta charset="utf-8">
  <title>yangbo</title>
  <meta content="yangbo" property="og:title">
  <meta content="yangbo" property="twitter:title">
  <meta content="width=device-width, initial-scale=1" name="viewport">
  <link href="css/normalize.css" rel="stylesheet" type="text/css">
  <link href="css/webflow.css" rel="stylesheet" type="text/css">
  <link href="css/shikais-stunning-site.webflow.css" rel="stylesheet" type="text/css">
  <script type="text/javascript">!function(o,c){var n=c.documentElement,t=" w-mod-";n.className+=t+"js",("ontouchstart"in o||o.DocumentTouch&&c instanceof DocumentTouch)&&(n.className+=t+"touch")}(window,document);</script>
  <link href="images/favicon.png" rel="shortcut icon" type="image/x-icon">
  <link href="images/webclip.png" rel="apple-touch-icon">
</head>
<body>
  <div id="yangboapp">
    <div data-animation="default" data-collapse="small" data-duration="400" data-easing="ease-in" data-easing2="ease" role="banner" class="navbar-3 w-nav">
      <div class="container-13 w-container">
        <div class="div-block-6">
          <form action="/search" class="search w-form"><input class="search-input w-input" autofocus="true" maxlength="256" name="query" v-model="domain" placeholder="搜索域名" type="search" id="search" required=""><img src="images/sousuoanniu.png" loading="lazy" data-w-id="5d7bba62-4656-a1b2-41e1-1ae21d423f08" v-on:click="getIpAddressFromFlask1()" alt="" class="image-3"></form>
        </div>
        <nav role="navigation" class="nav-menu-3 w-nav-menu">
          <div data-hover="false" data-delay="0" class="w-dropdown">
            <div class="yonghuxinxi w-dropdown-toggle">
              <div class="div-block-9"><img src="images/xinzengzhuti.svg" loading="lazy" width="36" alt="" class="image-16"></div>
            </div>
            <nav class="dropdown-list w-dropdown-list">
              <a href="#" class="dropdown-link yonghu_xuanze w-dropdown-link">新建主题</a>
              <a href="#" class="yonghu_xuanze w-dropdown-link">新建卡片</a>
            </nav>
          </div>
          <div data-hover="false" data-delay="0" class="w-dropdown">
            <div class="yonghuxinxi w-dropdown-toggle">
              <div class="div-block-9"><img src="images/weixintouxiang_lsk.jpg" loading="lazy" height="33" alt="" width="33" srcset="images/weixintouxiang_lsk-p-500.jpg 500w, images/weixintouxiang_lsk.jpg 516w" sizes="(max-width: 767px) 100vw, 33px" class="image-2"></div>
            </div>
            <nav class="dropdown-list w-dropdown-list">
              <a href="#" class="dropdown-link yonghu_xuanze w-dropdown-link">我的主题</a>
              <a href="#" class="dropdown-link yonghu_xuanze w-dropdown-link">个人中心</a>
              <a href="#" class="yonghu_xuanze w-dropdown-link">官网首页</a>
              <a href="#" class="yonghu_xuanze w-dropdown-link">退出登录</a>
            </nav>
          </div>
        </nav>
        <div class="w-nav-button">
          <div class="icon-2 iconzhnakai w-icon-nav-menu"></div>
        </div>
      </div>
    </div>
    <section>
      <div class="w-layout-blockcontainer container-25 w-container">
        <p class="paragraph-6">域名列表</p>
      </div>
    </section>
    <section class="section-14">
      <div id="yangbo" class="w-layout-blockcontainer container-26 w-container">
        <div class="html-embed-3 w-embed">
          <ul class="tree-list">
            <!--  第一层父节点  -->
            <li class="parent-node">
              VS_ecp
              <span class="child-node-with-status">
                <span class="icon square-icon"></span>
                172.21.253.166:80
              </span>
              <ul class="child-node">
                <!--  第二层子节点  -->
                <li class="child-node">
                  Pool_ecp
                  <ul class="child-node">
                    <!--  第三层子节点  -->
                    <li class="child-node-with-status">
                      <span class="icon circle-icon"></span>
                      172.21.253.147:80
                      <span class="status-icon status-online"></span>
                    </li>
                    <li class="child-node-with-status">
                      <span class="icon circle-icon"></span>
                      172.21.253.148:80
                      <span class="status-icon status-offline"></span>
                    </li>
                  </ul>
                </li>
              </ul>
            </li>
            <!--  第一层父节点  -->
            <li class="parent-node">
              VS_Test-ECP
              <!--  ... 其他节点及子节点 ...  -->
            </li>
            <!--  可以继续添加更多父节点  -->
          </ul>
        </div>
        <div class="html-embed-4 w-embed">
          <div id="app">
            <ul class="tree-list">
              <li v-for="node in treeData" :key="node.id" class="parent-node">
                {{ node.name }} <span v-if="node.ip">({{ node.ip }})</span>
                <span v-if="node.children && node.children.length" @click="toggle(node)">
                  <span class="icon" :class="{'square-icon': !node.open, 'circle-icon': node.open}"></span>
                </span>
                <template v-if="node.open">
                  <ul class="child-node">
                    <li v-for="child in node.children" :key="child.id">
                      {{ child.name }} <span v-if="child.ip">({{ child.ip }})</span>
                      <!--  递归子节点  -->
                      <span v-if="child.children && child.children.length" @click="toggle(child)">
                        <span class="icon" :class="{'square-icon': !child.open, 'circle-icon': child.open}"></span>
                      </span>
                      <template v-if="child.open">
                        <ul class="child-node">
                          <li v-for="subChild in child.children" :key="subChild.id">
                            {{ subChild.name }} <span v-if="subChild.ip">({{ subChild.ip }})</span>
                            <!--  继续递归...  -->
                          </li>
                        </ul>
                      </template>
                    </li>
                  </ul>
                </template>
              </li>
            </ul>
          </div>
        </div>
        <div class="w-embed">
          <div class="network-container">
            <div v-for="domainData in networkData" :key="domainData.domain" class="domain-container">
              <h2 class="domain-title">{{ domainData.domain }}</h2>
              <div v-for="ipData in domainData.ips" :key="ipData.ip" class="ip-container">
                <h3 class="ip-title">
                  <span class="icon square-icon"></span> <!--  假设每个IP都显示一个正方形的图标  -->
                  {{ ipData.ip }}
                </h3>
                <ul class="port-list">
                  <li v-for="portData in ipData.ports" :key="portData.port" class="port-list-item">
                    Port {{ portData.port }}
                    <ul class="connected-ip-list">
                      <li v-for="connectedIp in portData.connectedIps" :key="connectedIp.ip" class="connected-ip-list-item">
                        <span class="icon circle-icon"></span> <!--  圆形图标表示端口  -->
                        {{ connectedIp.ip }}
                        <span v-bind:class="['status-icon', connectedIp.status ? 'status-online' : 'status-offline']"></span>
                        <!--  状态图标，根据connectedIp.status的值显示不同颜色  -->
                      </li>
                    </ul>
                  </li>
                </ul>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  </div>
  <div class="vue-roota w-embed w-script">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
    <script>
 // 使用异步函数来执行DNS解析
async function getIpAddress(domain) {
  try {
    const ipAddresses = await new Promise((resolve, reject) => {
      // 使用浏览器的DNS解析功能
      const dnsResolver = new DNSResolver();
      dnsResolver.resolve(domain, (result) => {
        if (result.error) {
          reject(result.error);
        } else {
          resolve(result.addresses);
        }
      });
    });
    return ipAddresses;
  } catch (error) {
    console.error("DNS解析失败：", error);
    return null;
  }
}
 </script>
    <script>
 Vue.config.devtools = true;
    new Vue({
      el: '#yangboapp',
      data: {
        domainIp: '',
        responseData: {},
       domain: "baota.memlee.top", // 将您要查询的域名放在这里
    ipAddresses: [],
                networkData: [{domain: 'test.wchscu.net', ips: [{ip: '172.21.253.240', ports: [{port: 80, connectedIps: [{ ip: '172.21.232.13:80', status: true }, { ip: '172.21.232.16:80', status: false }, ], }, {port: 90, connectedIps: [{ ip: '172.21.232.13:90', status: true }, { ip: '172.21.232.16:90', status: true }, ], }, ], }, ], }, {domain: 'test.wchscu.net', ips: [{ip: '172.21.253.240', ports: [{port: 80, connectedIps: [{ ip: '172.21.232.13:80', status: true }, { ip: '172.21.232.16:80', status: false }, ], }, {port: 90, connectedIps: [{ ip: '172.21.232.13:90', status: true }, { ip: '172.21.232.16:90', status: true }, ], }, ], }, ], }],
        treeData:  [{id: 1, name: "VS_ecp", open: false, ip: "172.21.253.166:80", children: [{id: 11, name: "Pool_ecp", open: false, children: [{id: 111, name: "172.21.253.147:80", open: false, status: "online", children: [{id: 1111, name: "Child Level 3 - A", ip:"172.21.253.147:80", open: false, children: [{id: 11111, name: "Child Level 4 - A", open: false, children: [] }, {id: 11112, name: "Child Level 4 - B", open: false, children: [] } ] }, {id: 1112, name: "Child Level 3 - B", open: false, children: [{id: 11121, name: "Child Level 4 - C", open: false, children: [] }, {id: 11122, name: "Child Level 4 - D", open: false, children: [] } ] } ] }, {id: 112, name: "172.21.253.148:80", open: false, status: "offline", children: [{id: 1121, name: "Child Level 3 - C", open: false, children: [{id: 11211, name: "Child Level 4 - E", open: false, children: [] }, {id: 11212, name: "Child Level 4 - F", open: false, children: [] } ] }, {id: 1122, name: "Child Level 3 - D", open: false, children: [{id: 11221, name: "Child Level 4 - G", open: false, children: [] }, {id: 11222, name: "Child Level 4 - H", open: false, children: [] } ] } ] } ] } ] }, {id: 2, name: "VS_Test-ECP", open: false, children: [ ] } ]
      },
      methods: {
        toggle: function (node) {
          node.open = !node.open;
        },
         async resolveDomain() {
      this.ipAddresses = await getIpAddress(this.domain);
    },
    async getIpAddressFromFlask(domain) {
  try {
    const response = await fetch('http://124.221.227.41:3000/get-ip', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ domain: domain })
    });
    const data = await response.json();
    if (data.ip) {
      this.domainIp=data.ip
      this.ipAddresses.push(data.ip);
      console.log("======================")
      console.log("IP Address:", data.ip)
    }
  } catch (error) {
    console.error("请求 Flask 服务失败：", error);
  }
},
        async postRequestUrl(url) {
          try {
            const response = await fetch(url, {
              method: 'POST',
              headers: {
                'ngrok-skip-browser-warning': '',  // 注意：这个头部可能不必要，除非有特定用途
                'Content-Type': 'application/json',
                'Authorization': 'Basic YWRtaW46YWRtaW4='
              },
            });
            const data = await response.json();
            console.log(data);
            return data
            // 处理响应数据
          } catch (error) {
            console.error('请求错误：', error);
          }
        },
        async postRequest() {
          try {
            const response = await fetch('http://localhost:5000/virtual', {
              method: 'POST',
              headers: {
                'ngrok-skip-browser-warning': '',  // 注意：这个头部可能不必要，除非有特定用途
                'Content-Type': 'application/json',
                'Authorization': 'Basic YWRtaW46YWRtaW4='
              },
              body: JSON.stringify({ domain: 'baidu.com' })
            });
            const data = await response.json();
            console.log(data);
            this.responseData = data
            // 处理响应数据
          } catch (error) {
            console.error('请求错误：', error);
          }
        },
        async compareIpWithItems(domain) {
          const items = this.responseData.items || [];
          const posts = []
          for (const item of items) {
            const [destinationIp, port] = item.destination.split('/').pop().split(':');
            const poolReference = item.poolReference.link;
            if (destinationIp === this.domainIp) {
              console.log(`域名 ${this.domain} 的 IP 地址与 ${destinationIp} 相匹配。`);
              console.log(`端口：${port}, Pool 参考：${poolReference}`);
              const ret = await this.postRequestUrl(poolReference); // 使用 await
              const membersRef = ret.membersReference.link;
              const members = await this.postRequestUrl(membersRef); // 使用 await
              // 取出items下的所有name字段的作为ip地址，取出对应ip地址的state作为状态，并打印
              var memberList = []
              for (const member of members.items) {
                const memberIp = member.name;
                const memberState = member.state;
                console.log(`IP地址：${memberIp}, 状态：${memberState}`);
                //   构建member,形式为 [{ ip: '192.168.1.2:8080', status: true }]
                const memberObj = { ip: memberIp, status: memberState === 'up' };
                memberList.push(memberObj);
              }
              console.log(memberList);
            //   构建posts 形式为 [{port: 8080, connectedIps: [{ ip: '192.168.1.2:8080', status: true } ] } ]
              const postObj = { port: port, connectedIps: memberList };
              posts.push(postObj)
            } else {
              console.log(`域名 ${this.domain} 的 IP 地址与 ${destinationIp} 不匹配。`);
            }
          }
          console.log(posts);
        //   构建ips 内容如下： ips: [{ip: '192.168.1.1', ports: [{port: 8080, connectedIps: [{ ip: '192.168.1.2:8080', status: true } ] } ] } ]
          const ips = []
          const ipsObj = { ip: this.domainIp, ports: posts };
          ips.push(ipsObj);
          console.log(ips);
        //   构建networkData 内容如下：{domain: 'newdomain.net', ips: [{ip: '192.168.1.1', ports: [{port: 8080, connectedIps: [{ ip: '192.168.1.2:8080', status: true } ] } ] } ] }
          const networkData = [{ domain: this.domain, ips: ips }];
          console.log(networkData);
         // this.networkData = networkData
        },
         async getIpAddressFromFlask1(domain) {
          await this.getIpAddressFromFlask(this.domain);
          // 拿到这个之后开始进行拿到当前所有的visual
          await this.postRequest()
          await this.compareIpWithItems();
          console.log("=========")
          console.log(this.domain)
      },
      },
  mounted() {
   // await this.getIpAddressFromFlask(this.domain);
    //await this.postRequest()
    //await this.compareIpWithItems();
    console.log("=========")
    console.log(this.domain)
  },
    });
  </script>
  </div>
  <div class="w-embed w-script">
    <style>
.network-container {
  font-family: Arial, sans-serif;
}
.domain-container {
  background-color: #f7f7f7;
  margin-bottom: 10px;
  padding: 10px;
}
.domain-title {
  font-size: 1.25rem;
  color: #007bff;
  margin: 0;
  padding: 5px 0;
}
.ip-container {
  margin-left: 20px;
  padding: 5px;
  border-left: 2px dotted #6c757d;
}
.ip-title {
  font-size: 1rem;
  color: #6c757d;
  margin: 5px 0;
}
.port-list {
  list-style-type: none;
  padding-left: 20px;
}
.port-list-item {
  background-color: #ffffff;
  border: 1px solid #dee2e6;
  padding: 5px;
  margin-bottom: 5px;
  position: relative;
}
.port-list-item:before {
  content: '';
  position: absolute;
  left: -22px;
  top: 11px;
  height: 2px;
  width: 20px;
  background-color: #dee2e6;
}
.connected-ip-list {
  list-style-type: none;
  padding-left: 20px;
}
.connected-ip-list-item {
  color: #212529;
  margin: 2px 0;
}
/* Additional styles can be added to customize icons and statuses if needed */
.icon {
  /* Style for your icons */
}
.status-online {
  /* Style for online status */
}
.status-offline {
  /* Style for offline status */
}
/* Icon styles */
.icon {
  display: inline-block;
  width: 16px; /* or the size of your icons */
  height: 16px; /* or the size of your icons */
  background-size: contain;
  background-repeat: no-repeat;
  margin-right: 5px; /* space between icon and text */
}
/* Example specific icons */
.icon.square-icon {
  background-image: url('path-to-your-square-icon.png'); /* Replace with your icon path */
}
.icon.circle-icon {
  background-image: url('path-to-your-circle-icon.png'); /* Replace with your icon path */
}
/* Status styles */
.status-icon {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-left: 5px; /* space between text and status */
}
.status-online {
  background-color: #28a745; /* green color indicating online status */
}
.status-offline {
  background-color: #dc3545; /* red color indicating offline status */
}
/* Additional styles for specific use cases */
.status-icon.status-warning {
  background-color: #ffc107; /* yellow color indicating a warning or standby status */
}
.status-icon.status-inactive {
  background-color: #6c757d; /* grey color indicating inactive or unknown status */
}
</style>
    <script>
document.addEventListener('DOMContentLoaded', function() {
    const tree = document.querySelector('.tree-list');
    tree.addEventListener('click', function(event) {
        if (event.target.tagName === 'LI') {
            const children = event.target.children[0];
            if (children) {
                children.style.display = children.style.display === 'none' ? 'block' : 'none';
            }
        }
    });
});
</script>
    <style>
/* 设置列表的基本样式 */
.tree-list {
    list-style: none;  /* 移除列表前的默认符号 */
    padding-left: 0;  /* 移除默认的内边距 */
}
/* 设置每个主节点的样式 */
.tree-list .parent-node {
    padding: 10px;
    border: 1px solid #ccc; /* 添加边框 */
    margin-bottom: 5px; /* 添加节点间距 */
    background-color: #f7f7f7; /* 背景色 */
    position: relative;
}
/* 设置子节点的样式 */
.tree-list .child-node {
    padding-left: 20px; /* 子节点的缩进 */
    list-style-type: none;  /* 移除子节点前的默认符号 */
}
/* 设置不同层级的图标样式 */
.tree-list .icon {
    width: 10px;
    height: 10px;
    display: inline-block;
    margin-right: 5px;
}
.tree-list .circle-icon {
    background-color: blue;
    border-radius: 50%; /* 圆形图标 */
}
.tree-list .square-icon {
    background-color: #666;
    border-radius: 3px; /* 方形图标 */
}
.tree-list .child-node .icon {
    background-color: #888;
}
/* 设置在线状态的颜色 */
.tree-list .status-online {
    background-color: green;
}
.tree-list .status-offline {
    background-color: red;
}
/* 调整带有状态的节点样式 */
.tree-list .child-node-with-status {
    display: flex;
    align-items: center;
}
.tree-list .child-node-with-status .status-icon {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    margin-left: auto; /* 将状态图标推到右边 */
}
/* Parent node */
.section-14 .w-embed .parent-node{
 border-top-left-radius:5px;
 border-top-right-radius:5px;
 border-bottom-left-radius:5px;
 border-bottom-right-radius:5px;
}
</style>
  </div>
  <div class="w-embed">
    <style>
/* Heading */
#yangbo h2{
 text-align:left;
 padding-left:16px;
 margin-top:0px;
 padding-bottom:0px;
 transform:translatex(0px) translatey(0px);
 color:#777781;
}
/* Container */
#yangbo .ip-container{
 border-left-style:dashed;
 transform:translatex(0px) translatey(0px);
 border-left-width:1px;
 border-left-color:#919191;
}
/* Domain container */
#yangbo .w-embed .domain-container{
 border-top-left-radius:8px;
 border-top-right-radius:8px;
 border-bottom-left-radius:8px;
 border-bottom-right-radius:8px;
 border-style:solid;
 border-width:1px;
 border-color:#cccccc;
 transform:translatex(0px) translatey(0px);
}
/* Heading */
#yangbo h3{
 padding-top:-1px;
 margin-top:-7px;
}
/* Port list item */
#yangbo .port-list .port-list-item{
 background-color:#ffffff;
}
/* Network container */
/* Embed */
/* Domain container */
#yangbo .w-embed .domain-container{
 transform:translatex(0px) translatey(0px);
 margin-right:13px;
 padding-left:4px;
 padding-right:15px;
}
/* Port list item */
#yangbo .port-list .port-list-item{
 border-top-left-radius:8px;
 border-top-right-radius:8px;
 border-bottom-left-radius:8px;
 border-bottom-right-radius:8px;
}
</style>
  </div>
  <script src="https://d3e54v103j8qbb.cloudfront.net/js/jquery-3.5.1.min.dc5e7f18c8.js?site=657c661418a503e0b43c9905" type="text/javascript" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
  <script src="js/webflow.js" type="text/javascript"></script>
</body>
</html>